package net.kazed.nextaction.context.activity;

import java.util.ArrayList;
import java.util.List;

import net.kazed.nextaction.ApplicationResource;
import net.kazed.nextaction.NextActionApplication;
import net.kazed.nextaction.R;
import net.kazed.nextaction.database.ContextCache;
import net.kazed.nextaction.database.GtdContext;
import net.kazed.nextaction.database.Task;
import net.kazed.nextaction.database.TreeNode;
import net.kazed.nextaction.database.GtdContext.Column;
import android.app.Activity;
import android.app.ExpandableListActivity;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.util.SparseIntArray;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ListAdapter;
import android.widget.SimpleCursorAdapter;
import android.widget.SimpleCursorTreeAdapter;

/**
 * Display tree of contexts.
 */
public class ContextTreeActivity extends ExpandableListActivity {

   public static final String SELECTED_ITEM = "SELECTED_ITEM";
   
   private static final int INSERT_ID = Menu.FIRST;

	private static final String cTag = "ContextsActivity";
	private static final int NEW_ITEM = 1;
   private static final int EDIT_ITEM = 2;
   
   private static final int MENU_INSERT_CONTEXT = Menu.FIRST;
	
   private Long mItemIdToSelect = null;
   
   private ExpandableListAdapter expandableListAdapter;
   private int mGroupIdColumnIndex; 
  private SparseIntArray mTaskCountArray;
  private ApplicationResource applicationResource;

   /**
    * Cursor to select for list of items
    */
//   protected Cursor cursor;

   @Override
   public void onCreate(Bundle icicle) {
      super.onCreate(icicle);
      NextActionApplication application = (NextActionApplication) getApplication();
      applicationResource = application.getApplicationResource();
      
      setContentView(R.layout.context_tree);
      setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT);
      // If no data was given in the intent (because we were started
      // as a MAIN activity), then use our default content provider.
      Intent intent = getIntent();
      if (intent.getData() == null) {
         intent.setData(getContentUri());
      }
      
      setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT);
      getExpandableListView().setLongClickable(true);
      registerForContextMenu(getExpandableListView());
      
      
//      getExpandableListView().setOnItemLongClickListener(new OnItemLongClickListener() {
//         @Override
//         public boolean onItemLongClick(AdapterView<?> parent, View view, int groupPosition, long id) {
//            Cursor cursor = (Cursor) expandableListAdapter.getGroup(groupPosition);
//            GtdContext context = new GtdContext(cursor);
//            Uri uri = ContentUris.withAppendedId(GtdContext.CONTENT_ITEM_URI, context.getId());
//            Intent intent = new Intent(Intent.ACTION_INSERT, uri);
//            startActivityForResult(intent, NEW_ITEM);
//            return true;
//         }
//         
//      });
      
      ContextCache contextCache = application.getContextCache();
      TreeNode<GtdContext> rootNode = contextCache.getContextTree();
      List<GtdContext> contextList = new ArrayList<GtdContext>();
      for (TreeNode<GtdContext> node : rootNode.getChildren()) {
          contextList.add(node.getData());
      }

      
//      Cursor groupCursor = managedQuery(GtdContext.CONTENT_URI, GtdContext.FULL_PROJECTION.getFieldNames(),
//            Column.PARENT_CONTEXT_ID + " is null", null, GtdContext.NAME + " ASC");
//      mGroupIdColumnIndex = groupCursor.getColumnIndex(GtdContext.ID);
//      // Set up our adapter
//      expandableListAdapter = new MyExpandableListAdapter(this, 
//            groupCursor, android.R.layout.simple_expandable_list_item_1,
//            android.R.layout.simple_expandable_list_item_1,
//            new String[] {GtdContext.NAME}, 
//            new int[] {android.R.id.text1},
//            new String[] {GtdContext.NAME},
//            new int[] {android.R.id.text1}); 
      
      expandableListAdapter = new TreeExpandableListAdapter(rootNode.getChildren());
      setListAdapter(expandableListAdapter);
   }

   @Override
	protected void onResume() {
		super.onResume();
	}
	
   @Override
   public boolean onCreateOptionsMenu(Menu menu) {
      String menuName = getResources().getString(R.string.menu_add_context);
      MenuItem item = menu.add(0, MENU_INSERT_CONTEXT, 0, menuName)
         .setIcon(android.R.drawable.ic_menu_add);
      item.setAlphabeticShortcut('a');
      return super.onCreateOptionsMenu(menu);
   }
   
//   @Override
//   protected void onListItemClick(ListView l, View v, int position, long id) {
//      Uri itemUri = ContentUris.withAppendedId(getContentUri(), id);
//
//      String action = getIntent().getAction();
//      if (Intent.ACTION_PICK.equals(action)
//            || Intent.ACTION_GET_CONTENT.equals(action)) {
//         // The caller is waiting for us to return a task selected by
//         // the user. They have clicked on one, so return it now.
//         Bundle bundle = new Bundle();
//          bundle.putString(SELECTED_ITEM, itemUri.toString());
//          Intent intent = new Intent();
//          intent.putExtras(bundle);
//          setResult(RESULT_OK, intent);        
//      } else {
//         // Launch activity to view/edit the currently selected item
//         Intent intent = new Intent();
//         Bundle bundle = new Bundle();
//         bundle.putString(SELECTED_ITEM, itemUri.toString());
//         intent.putExtras(bundle);
//         intent.setData(itemUri);
//         intent.setAction(Intent.ACTION_VIEW);
//         startActivityForResult(intent, EDIT_ITEM);
//      }
//   }

   @Override
   public boolean onOptionsItemSelected(MenuItem item) {
      switch (item.getItemId()) {
      case MENU_INSERT_CONTEXT:
         View selecteditem = getExpandableListView().getSelectedView();
         long contextId = getExpandableListView().getSelectedItemId();
         Uri uri = ContentUris.withAppendedId(GtdContext.CONTENT_ITEM_URI, contextId);
         Intent intent = new Intent(Intent.ACTION_INSERT, uri);
         startActivityForResult(intent, NEW_ITEM);
         break;
      }
      return super.onOptionsItemSelected(item);
   }
   
   /**
    * {@inheritDoc}
    */
   
   @Override
   public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
      Resources resources = getResources();
      menu.add(0, MENU_INSERT_CONTEXT, 0, resources.getString(R.string.menu_add_context))
         .setIcon(android.R.drawable.ic_menu_add).setAlphabeticShortcut('i');
   }
   
   @Override
   public boolean onContextItemSelected(MenuItem item) {
      switch (item.getItemId()) {
      case MENU_INSERT_CONTEXT:
         long contextId = getExpandableListView().getSelectedItemId();
         Uri uri = ContentUris.withAppendedId(GtdContext.CONTENT_ITEM_URI, contextId);
         Intent intent = new Intent(Intent.ACTION_INSERT, uri);
         startActivityForResult(intent, NEW_ITEM);
         break;
      }
      return super.onContextItemSelected(item);
   }

   @Override
   public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
      Log.i(cTag, "onChildClick: " + groupPosition + ", " + childPosition + ", " + id);
      return super.onChildClick(parent, v, groupPosition, childPosition, id);
   }

   @Override
   protected void onActivityResult(int requestCode, int resultCode,
         Intent data) {
      switch (requestCode) {
      case NEW_ITEM:
         if (resultCode == Activity.RESULT_OK) {
            if (data != null) {
               Uri uri = Uri.parse(data.getStringExtra(SELECTED_ITEM));
               mItemIdToSelect = ContentUris.parseId(uri);
               // need to do the actual checking and selecting
               // in onResume, otherwise getItemId(i) is always 0
               // and setSelection(i) does nothing
            }
         }
         break;
      default:
         Log.e(cTag, "Unknown requestCode: " + requestCode);
      break;
      }
   }
   
   /**
    * @return Number of items in the list.
    */
//   protected final int getItemCount() {
//      return cursor.getCount();
//   }

	protected int getContentViewResId() {
		return R.layout.contexts;
	}

	protected Uri getContentUri() {
		return GtdContext.CONTENT_URI;
	}
	
	protected Uri getChildContentUri() {
		return Task.CONTENT_URI;
	}
	
	String getChildName() {
		return getString(R.string.task_name);
	}
	
	protected void deleteChildren(int groupId) {
		getContentResolver().delete(getChildContentUri(), Task.Column.CONTEXT_ID + " = ?", new String[] {String.valueOf(groupId)});
	}

	protected ListAdapter createListAdapter(Cursor cursor) {
		ListAdapter adapter =
				new SimpleCursorAdapter(this,
						android.R.layout.simple_list_item_1, cursor,
						new String[] { GtdContext.NAME },
						new int[] { android.R.id.text1 }) {
			
			public View getView(int position, View convertView, ViewGroup parent) {
			   Cursor cursor = (Cursor) getItem(position);
			   GtdContext context = readGtdContext(cursor);

				ContextView contextView;
				if (convertView instanceof ContextView) {
					contextView = (ContextView) convertView;
				} else {
					contextView = new ContextView(parent.getContext());
				}
//				contextView.setTaskCountArray(mTaskCountArray);
//				boolean isSelected = false;
				contextView.updateView(context);
				return contextView;
			}


		};
		return adapter;
	}
	
   private GtdContext readGtdContext(Cursor cursor) {
      GtdContext context = new GtdContext(cursor);
      return context;
   }
	
   protected int getGroupIdColumnIndex() {
      return mGroupIdColumnIndex;
   }

    /**
     * Return the intent generated when a list item is clicked.
     * 
     * @param url type of data selected
     */ 
//    protected Intent getClickIntent(Uri uri) {
//    	// if a context is clicked on, show context view.
//    	Intent intent = new Intent(this, ContextViewActivity.class);
//    	intent.setData(uri);
//    	return intent;
//    }
	
    protected GtdContext readItem(Cursor c) {
        return readGtdContext(c);
    }

     /**
      * Permanently delete the selected item.
      */
//     protected void deleteItem() {
//       int childCount = getSelectedItemChildCount();
//       if (childCount > 0) {
//          final int groupId = (int)getSelectedItemId();
//          OnClickListener buttonListener = new OnClickListener() {
//             public void onClick(DialogInterface dialog, int which) {
//                if (which == DialogInterface.BUTTON2) {
//                   Log.i(cTag, "Deleting group id " + groupId);
//                   deleteChildren(groupId);
//                } else {
//                   Log.d(cTag, "Hit Cancel button. Do nothing.");
//                }
//             }
//          };
//       }
//     }

    protected boolean supportsViewAction() {
       return false;
    }
    
//    protected Cursor createChildQuery(long groupId) {
//       Cursor cursor = managedQuery(Task.CONTENT_URI, Task.FULL_PROJECTION.getFieldNames(),
//             Task.CONTEXT_ID + " = ?", new String[] {String.valueOf(groupId)}, 
//             Task.CREATED_DATE + " ASC");
//       mChildIdColumnIndex = cursor.getColumnIndex(Task.ID);
//       return cursor;
//    }

    public class MyExpandableListAdapter extends SimpleCursorTreeAdapter {
       
       private int mChildIdColumnIndex;

       public MyExpandableListAdapter(Context context, Cursor cursor, int groupLayout,
               int childLayout, String[] groupFrom, int[] groupTo, String[] childrenFrom,
               int[] childrenTo) {
           super(context, cursor, groupLayout, groupFrom, groupTo, childLayout, childrenFrom,
                   childrenTo);
       }

       @Override
       protected Cursor getChildrenCursor(Cursor groupCursor) {
        long groupId = groupCursor.getLong(getGroupIdColumnIndex());
        Log.d(cTag, "getChildrenCursor for groupId " + groupId);
        Cursor cursor = managedQuery(GtdContext.CONTENT_URI, GtdContext.FULL_PROJECTION.getFieldNames(),
              Column.PARENT_CONTEXT_ID + " = ?", new String[] {String.valueOf(groupId)}, 
              GtdContext.NAME + " ASC");
        mChildIdColumnIndex = cursor.getColumnIndex(Task.Column.ID);
        return cursor;
       }
       
       @Override
       public long getGroupId(int groupPosition) {
        Log.d(cTag, "getGroupId " + groupPosition);
        Cursor groupCursor = (Cursor) getGroup(groupPosition); // groupCursor is sometimes null
        long groupId = groupCursor.getLong(getGroupIdColumnIndex());
        return groupId;
       }
       
       @Override
       public long getChildId(int groupPosition, int childPosition) {
        Log.d(cTag, "getChildId " + groupPosition + "," + childPosition);
        Cursor childCursor = (Cursor) getChild(groupPosition, childPosition);
        long childId = childCursor.getLong(mChildIdColumnIndex);
        return childId;
       }
       
//       public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
//         Cursor cursor = (Cursor) getChild(groupPosition, childPosition);
//         Task task = readChild(cursor);
//         TaskView taskView;
//         if (convertView instanceof ExpandableTaskView) {
//            taskView = (ExpandableTaskView) convertView;
//         } else {
//            taskView = new ExpandableTaskView(parent.getContext(), false);
//         }
//         boolean isSelected = false;
//         taskView.updateView(task, isSelected);
//         return taskView;
//      }

         public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
          Cursor cursor = (Cursor) getGroup(groupPosition);
          GtdContext context = new GtdContext(cursor);
          ExpandableContextView contextView = null;
          if (convertView instanceof ExpandableContextView) {
             contextView = (ExpandableContextView) convertView;
          } else {
             contextView = new ExpandableContextView(parent.getContext());
          }
//          contextView.setTaskCountArray(mTaskCountArray);
//          boolean isSelected = false;
          contextView.updateView(context);
          return contextView;
         }

   }
    
    public class TreeExpandableListAdapter extends BaseExpandableListAdapter {
       
       private List<TreeNode<GtdContext>> nodeList;

       public TreeExpandableListAdapter(List<TreeNode<GtdContext>> nodeList) {
           super();
           this.nodeList = nodeList;
       }

       @Override
       public long getGroupId(int groupPosition) {
        Log.d(cTag, "getGroupId " + groupPosition);
        TreeNode<GtdContext> node = nodeList.get(groupPosition);
        return node.getData().getId();
       }
       
       @Override
       public long getChildId(int groupPosition, int childPosition) {
        Log.d(cTag, "getChildId " + groupPosition + "," + childPosition);
        TreeNode<GtdContext> parentNode = nodeList.get(groupPosition);
        TreeNode<GtdContext> childNode = parentNode.getChildren().get(childPosition);
        return childNode.getData().getId();
       }
       
//       public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
//         Cursor cursor = (Cursor) getChild(groupPosition, childPosition);
//         Task task = readChild(cursor);
//         TaskView taskView;
//         if (convertView instanceof ExpandableTaskView) {
//            taskView = (ExpandableTaskView) convertView;
//         } else {
//            taskView = new ExpandableTaskView(parent.getContext(), false);
//         }
//         boolean isSelected = false;
//         taskView.updateView(task, isSelected);
//         return taskView;
//      }

         public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
            TreeNode<GtdContext> parentNode = nodeList.get(groupPosition);
             GtdContext context = parentNode.getData();
             ExpandableContextView contextView;
             if (convertView instanceof ExpandableContextView) {
                contextView = (ExpandableContextView) convertView;
             } else {
                contextView = new ExpandableContextView(parent.getContext());
             }
//          contextView.setTaskCountArray(mTaskCountArray);
//          boolean isSelected = false;
             contextView.updateView(context);
             return contextView;
         }

         @Override
         public Object getChild(int groupPosition, int childPosition) {
            TreeNode<GtdContext> parentNode = nodeList.get(groupPosition);
            TreeNode<GtdContext> childNode = parentNode.getChildren().get(childPosition);
            return childNode.getData();
         }

         @Override
         public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView,
               ViewGroup parent) {
            TreeNode<GtdContext> parentNode = nodeList.get(groupPosition);
            TreeNode<GtdContext> childNode = parentNode.getChildren().get(childPosition);
            GtdContext context = childNode.getData();
            ExpandableContextView contextView = null;
            if (convertView instanceof ExpandableContextView) {
               contextView = (ExpandableContextView) convertView;
            } else {
               contextView = new ExpandableContextView(parent.getContext());
            }
//         contextView.setTaskCountArray(mTaskCountArray);
//         boolean isSelected = false;
            contextView.updateView(context);
            return contextView;
         }

         @Override
         public int getChildrenCount(int groupPosition) {
            TreeNode<GtdContext> node = nodeList.get(groupPosition);
            return node.getChildren().size();
         }

         @Override
         public Object getGroup(int groupPosition) {
            TreeNode<GtdContext> node = nodeList.get(groupPosition);
            return node.getData();
         }

         @Override
         public int getGroupCount() {
            return nodeList.size();
         }

         @Override
         public boolean hasStableIds() {
            return true;
         }

         @Override
         public boolean isChildSelectable(int groupPosition, int childPosition) {
            // TODO Auto-generated method stub
            return true;
         }

   }


}